Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.

...powered by www.netzwerkartist.de...

Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Sprachbeschreibung
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Mathematisches
6 Eigene Klassen schreiben
7 Exceptions
8 Die Funktionsbibliothek
9 Threads und nebenläufige Programmierung
10 Raum und Zeit
11 Datenstrukturen und Algorithmen
12 Dateien und Datenströme
13 Die eXtensible Markup Language (XML)
14 Grafische Oberflächen mit Swing
15 Grafikprogrammierung
16 Das Netz
17 JavaServer Pages und Servlets
18 Verteilte Programmierung mit RMI und Web–Services
19 Applets, Midlets und Sound
20 Datenbankmanagement mit JDBC
21 Reflection und Annotationen
22 Komponenten durch Bohnen
23 Logging und Monitoring
24 Sicherheitskonzepte
25 Java Native Interface (JNI)
26 Dienstprogramme für die Java-Umgebung
A Die Begleit-DVD
Index

Download:
- ZIP, ca. 12,5 MB
Buch bestellen

Website zum Buch
Weblog des Autors
Ihre Meinung?

Spacer
 <<   zurück
Java ist auch eine Insel von Christian Ullenboom
Programmieren mit der Java Standard Edition Version 6
Buch: Java ist auch eine Insel

Java ist auch eine Insel
6., akt. und erw. Aufl., mit DVD
1.454 S., 49,90 Euro
Galileo Computing
ISBN 3-89842-838-9
gp 13 Die eXtensible Markup Language (XML)
  gp 13.1 Auszeichnungssprachen
    gp 13.1.1 Die Standard Generalized Markup Language (SGML)
    gp 13.1.2 Extensible Markup Language (XML)
  gp 13.2 Eigenschaften von XML-Dokumenten
    gp 13.2.1 Elemente und Attribute
    gp 13.2.2 Beschreibungssprache für den Aufbau von XML-Dokumenten
    gp 13.2.3 Schema – eine Alternative zu DTD
    gp 13.2.4 Namensraum (Namespace)
    gp 13.2.5 XML-Applikationen
  gp 13.3 Die Java-APIs für XML
    gp 13.3.1 Das Document Object Model (DOM)
    gp 13.3.2 Simple API for XML Parsing (SAX)
    gp 13.3.3 Pull-API StAX
    gp 13.3.4 Java Document Object Model (JDOM)
    gp 13.3.5 JAXP als Java-Schnittstelle zu XML
    gp 13.3.6 DOM-Bäume einlesen mit JAXP
  gp 13.4 Serielle Verarbeitung mit StAX
    gp 13.4.1 Unterschiede der Verarbeitungsmodelle
    gp 13.4.2 XML-Dateien mit dem Cursor-Verfahren lesen
    gp 13.4.3 XML-Dateien mit dem Iterator-Verfahren verarbeiten
    gp 13.4.4 Mit Filtern arbeiten
    gp 13.4.5 XML-Dokumente schreiben
  gp 13.5 Serielle Verarbeitung von XML mit SAX
    gp 13.5.1 Schnittstellen von SAX
    gp 13.5.2 SAX-Parser erzeugen
    gp 13.5.3 Die wichtigsten Methoden der Schnittstelle ContentHandler
    gp 13.5.4 ErrorHandler und EntityResolver
  gp 13.6 XML-Dateien mit JDOM verarbeiten
    gp 13.6.1 JDOM beziehen
    gp 13.6.2 Paketübersicht
    gp 13.6.3 Die Document-Klasse
    gp 13.6.4 Eingaben aus der Datei lesen
    gp 13.6.5 Das Dokument im XML-Format ausgeben
    gp 13.6.6 Der Dokumenttyp
    gp 13.6.7 Elemente
    gp 13.6.8 Zugriff auf Elementinhalte
    gp 13.6.9 Liste mit Unterelementen erzeugen
    gp 13.6.10 Neue Elemente einfügen und ändern
    gp 13.6.11 Attributinhalte lesen und ändern
    gp 13.6.12 XPath
  gp 13.7 Transformationen mit XSLT
    gp 13.7.1 Templates und XPath als Kernelemente von XSLT
    gp 13.7.2 Umwandlung von XML-Dateien mit JDOM und JAXP
  gp 13.8 Java Architecture for XML Binding (JAXB)
  gp 13.9 HTML-Dokumente einlesen
  gp 13.10 Zum Weiterlesen


Galileo Computing

13.5 Serielle Verarbeitung von XML mit SAX  downtop

Die Verarbeitung von XML-Dateien mit SAX ist vor dem Erscheinen von StAX die schnellste und speicherschonendste Methode gewesen. Der Parser liest die XML-Datei seriell, und ruft für jeden Bestandteil der XML-Datei eine spezielle Methode auf. Der Nachteil ist, dass immer nur ein kleiner Bestandteil einer XML-Datei betrachtet wird und nicht die gesamte Struktur zur Verfügung steht.


Galileo Computing

13.5.1 Schnittstellen von SAX  downtop

Die Ereignisse, die bei der Verarbeitung mit SAX anfallen, sind in verschiedenen Schnittstellen festgelegt. Die wichtigste Schnittstelle ist org.xml.sax.ContentHandler. Die Schnittstelle legt die wichtigsten Methoden für die Verarbeitung fest, denn die Methoden ruft der Parser beim Verarbeiten der XML-Daten auf.

Die Klasse org.xml.sax.helpers.DefaultHandler ist eine leere Implementierung aller Operationen aus ContentHandler. Zusätzlich implementiert DefaultHandler die Schnittstellen DTDHandler, EntityResolver und ErrorHandler. Auf diese Schnittstellen wird hier nicht näher eingegangen. Eine genaue Beschreibung ist in dem JAXP-Tutorial von Sun (http://java.sun.com/webservices/jaxp/docs.html) zu finden.


Galileo Computing

13.5.2 SAX-Parser erzeugen  downtop

Um zum Parsen einer Datei zu kommen, führt der Weg über zwei Fabrikmethoden.

Listing 13.12    com/javatutor/insel/sax/SaxParty.java, main()

SAXParserFactory factory = SAXParserFactory.newInstance(); 
SAXParser saxParser = factory.newSAXParser();

Mit dem SAXParser erledigt parse() das Einlesen. Die Methode benötigt die Datei und eine Implementierung der Callback-Funktionen, die wir als PartyHandler bereitstellen.

Listing 13.13    com/javatutor/insel/sax/SaxParty.java, main()

DefaultHandler handler = new PartyHandler(); 
saxParser.parse( new File("party.xml"), handler );

Galileo Computing

13.5.3 Die wichtigsten Methoden der Schnittstelle ContentHandler  downtop

DefaultHandler ist eine Klasse, die alle Operationen aus EntityResolver, DTDHandler, ContentHandler und ErrorHandler leer implementiert. Unsere Unterklasse PartyHandler erweitert die Klasse DefaultHandler und überschreibt interessantere Funktionen, die wir mit Leben füllen wollen.

Listing 13.14    com/javatutor/insel/sax/PartyHandler.java

package com.javatutor.insel.sax; 
 
import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 
 
class PartyHandler extends DefaultHandler 
{

Beim Start und Ende des Dokuments ruft der Parser die Methoden startDocument() und endDocument() auf. Unsere überschriebenen Methoden geben nur eine kleine Meldung auf dem Bildschirm aus:

  @Override 
  public void startDocument() 
  { 
    System.out.println( "Document starts." ); 
  } 
 
  @Override 
  public void endDocument() 
  { 
    System.out.println( "Document ends." ); 
  }

Sobald der Parser ein Element erreicht, ruft er die Methode startElement() auf. Der Parser übergibt der Methode die Namensraumadresse, den lokalen Namen, den qualifizierenden Namen und Attribute.

  @Override 
  public void startElement( String namespaceURI, String localName, 
                            String qName, Attributes atts ) throws SAXException 
  { 
    System.out.println( "namespaceURI: " + namespaceURI ); 
    System.out.println( "localName: " + localName ); 
    System.out.println( "qName: " + qName ); 
 
    for ( int i = 0; i < atts.getLength(); i++ ) 
      System.out.printf( "Attribut no. %d: %s = %s%n", i, 
                         atts.getQName( i ), atts.getValue( i ) ); 
  }

Unsere Methode gibt alle notwendigen Informationen eines Elements aus. Falls kein spezieller Namensraum vergeben ist, sind die Strings namespaceURI und localName leer. Der String qName ist immer gefüllt. Die Attribute enthält der Container Attributes. Das schließende Tag eines Elements verarbeitet die Methode endElement(String namespaceURI, String localName, String qName). Bis auf die Attribute sind auch bei dem schließenden Tag alle Informationen für die Identifizierung des Elements vorhanden. Auch hier sind die Strings namespaceURI und localName leer, falls kein spezieller Namensraum verwendet wird.

Den Inhalt eines Elements verarbeitet unsere letzte Methode characters():

  @Override 
  public void characters( char[] ch, int start, int length ) 
  { 
    System.out.println( "Characters:" ); 
 
    for ( int i = start; i < (start + length); i++ ) 
      System.out.printf( "%1$c (%1$x) ", (int) ch[i] ); 
 
    System.out.println(); 
  } 
}

Es ist nicht festgelegt, ob der Parser den Text an einem Stück liefert oder in kleinen Stücken. Zur besseren Sichtbarkeit geben wir neben dem Zeichen selbst auch seinen Hexadezimalwert aus. So beginnt die Ausgabe mit den Zeilen:

Document starts. 
namespaceURI: 
localName: 
qName: party 
Attribut no. 0: datum = 31.12.01 
Characters: 
 
 (a) 
 (a)   (20)   (20)   (20) 
namespaceURI: 
localName: 
qName: gast 
Attribut no. 0: name = Albert Angsthase 
Characters: 
 
 (a)   (20)   (20)   (20)   (20)   (20)   (20) 
namespaceURI: 
localName: 
qName: getraenk 
Characters: 
W (57) e (65) i (69) n (6e) 
Characters: 
 
 (a)   (20)   (20)   (20)   (20)   (20)   (20) 
namespaceURI: 
localName: 
qName: getraenk 
Characters: 
B (42) i (69) e (65) r (72)

Galileo Computing

13.5.4 ErrorHandler und EntityResolver  toptop

Immer dann, wenn der Parser einen Fehler melden muss, ruft er die im ErrorHandler deklarierten Operationen auf.

  • void warning( SAXParseException exception )
  • void error( SAXParseException exception )
  • void fatalError( SAXParseException exception )

Da der DefaultHandler die Methoden warning() und error() leer implementiert, fällt kein Fehler wirklich auf; nur bei fatalError() leitet die Methode den empfangenen Fehler mit throw weiter. Das heißt aber auch, dass zum Beispiel schwache Validierungsfehler nicht auffallen. Eine Implementierung kann aber wie folgt aussehen:

public void error( SAXParseException e ) throws SAXException 
{ 
  throw new SAXException( saxMsg(e) ); 
} 
private String saxMsg( SAXParseException e ) 
{ 
  return   "Line: " + e.getLineNumber() + ", Column: " 
         + e.getColumnNumber() + ", Error: " + e.getMessage(); 
}

Die Klasse DefaultHandler implementiert ebenso die Schnittstelle EntityResolver, aber auch hier einfach die eine Methode InputSource resolveEntity (String publicId, String systemId) mit einem return null. Das heißt, die Standardimplementierung löst keine Entities auf. Eigene Implementierungen sehen meist im Kern so aus:

InputStream stream = MyEntityResolver.class.getResourceAsStream( dtd ); 
return new InputSource( new InputStreamReader( stream ) );

Die Variable dtd ist mit dem Pfadnamen einer DTD belegt, die im Klassenpfad liegen muss.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.





 <<   zurück



Copyright © Galileo Press 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de